package com.pro.xwt.rest.aspect;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.pro.xwt.common.model.BEmployee;
import com.pro.xwt.common.model.BLog;
import com.pro.xwt.common.model.BTask;
import com.pro.xwt.common.service.BEmployeeService;
import com.pro.xwt.common.service.BLogService;
import com.pro.xwt.common.service.BTaskService;
import com.pro.xwt.common.utils.Common;
@Component
@Aspect
public class LogAspect {
	@Autowired
	BLogService bLogService;
	@Autowired
	BTaskService bTaskService;
	@Autowired
	BEmployeeService bEmployeeService;
	
	
	/**
	 * 添加业务逻辑方法切入点 定义在controller包里的以add为前缀的方法的执行
	 */
	@Pointcut("execution(* com.pro.xwt.rest.controller.BTaskController.add(..))")
	public void insertServiceCall() {
		
		}
	/**
	 * 修改业务逻辑方法定义在controller包里的以add为前缀的方法的执行
	 */
    @Pointcut("execution(* com.pro.xwt.rest.controller.BTaskController.update(..))")
	public void updateServiceCall(){
	}
    
    /**
	 * 修改业务逻辑方法定义在controller包里的以add为前缀的方法的执行
	 */
    @Pointcut("execution(* com.pro.xwt.file.controller.FilesController.upload(..))")
	public void uploadServiceCall(){
	}
    
    
    
    @Pointcut("execution(* com.pro.xwt.rest.controller.LoginController.login(..))")
   	public void loginServiceCall(){
   	}
    
    
    /**
     * 登录操作
     * @param joinPoint
     * @param rtv
     * @throws Throwable
     */
    @AfterReturning(value="loginServiceCall()", argNames = "rtv", returning = "rtv")
	public void loginServiceCall(JoinPoint joinPoint, Object rtv)
			throws Throwable {
		if (joinPoint.getArgs() == null) {// 没有参数
			return;
		}
			Date date = new Date();
			BLog blog = new BLog();
			Map<String,Object> map = new HashMap<>();
			String methodName = joinPoint.getSignature().getName();
			String userName = (String) adminOptionInfo(joinPoint.getArgs(),methodName).get("getUsername");
			String password = (String) adminOptionInfo(joinPoint.getArgs(),methodName).get("getPassword");
			map.put("userName",userName);
			map.put("password",password);
			List<BEmployee> bEmployee=bEmployeeService.queryListAll(map);
			
		if(bEmployee.size()>0){
			
			String empName=bEmployee.get(0).getName();
			String empId = bEmployee.get(0).getId();
			String content =empName+"登陆了宣臻协作任务系统";
			blog.setId(Common.generateUUID());
			blog.setContent(content);
			blog.setCreateTime(date);
			blog.setDeleteState("0");
			blog.setEmpId(empId);
			blog.setEmpName(empName);
			blog.setType("LOGIN");
			bLogService.insert(blog);
		
		}
	} 
    
    
    
    /**
	 * 任务完成日志(后置通知)
	 * 
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value="updateServiceCall()", argNames = "rtv", returning = "rtv")
	public void updateServiceCallCalls(JoinPoint joinPoint, Object rtv)
			throws Throwable {
		if (joinPoint.getArgs() == null) {// 没有参数
			return;
		}
		BLog bLog = new BLog();
		Object[] canshu = joinPoint.getArgs();
		String id =(String) canshu[0] ;
		BTask bTasks =bTaskService.findById(id);
		HttpServletRequest request = (HttpServletRequest) canshu[2];
		Object comState = ((Map<String, Object>) canshu[1]).get("comState");
		BEmployee user =(BEmployee) request.getAttribute("user");
		bLog.setId(Common.generateUUID());
		bLog.setType("OPERATE");
		String content=null;
		if(comState.equals("0")){
		    content = "取消了任务"+bTasks.getDescription()+"完成状态";
		    bLog.setEmpId(user.getId());
		    bLog.setEmpName(user.getName());
			bLog.setContent(content);
		}else{
			content = "完成了任务"+bTasks.getDescription();
			bLog.setEmpId(bTasks.getExecEmpId());
			bLog.setEmpName(bTasks.getExecEmpName());
			bLog.setContent(content);
		}
		bLog.setDeleteState("0");
		bLog.setProjId(bTasks.getProjId());
		bLog.setCreateTime(new Date());
		bLogService.insert(bLog);	
	}
	
	/**
	 * 创建任务后置通知
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value="insertServiceCall()", argNames = "rtv", returning = "rtv")
	public void insertServiceCallCalls(JoinPoint joinPoint, Object rtv)
			throws Throwable {
		if (joinPoint.getArgs() == null) {// 没有参数
			return;
		}
		BLog bLog = new BLog();
		// 获取方法名
		String methodName = joinPoint.getSignature().getName();
		// 员工id
		String empId = (String) adminOptionInfo(joinPoint.getArgs(),methodName).get("getCreateEmpId");
		//员工姓名
		HttpServletRequest request = (HttpServletRequest) joinPoint.getArgs()[1];
		BEmployee user=(BEmployee) request.getAttribute("user");
		String empName=user.getName();
		//项目id
		String projId = (String) adminOptionInfo(joinPoint.getArgs(),methodName).get("getProjId");
		//任务内容
		String content =(String) adminOptionInfo(joinPoint.getArgs(),methodName).get("getDescription");
		content="创建了任务"+" "+content;
		
		bLog.setId(Common.generateUUID());
		bLog.setEmpId(empId);
		bLog.setEmpName(empName);
		bLog.setContent(content);
		bLog.setDeleteState("0");
		bLog.setProjId(projId);
		bLog.setCreateTime(new Date());
		bLog.setType("OPERATE");
		bLogService.insert(bLog);	
	}
	
	/**
	 * 上传文件后置操作
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value="uploadServiceCall()", argNames = "rtv", returning = "rtv")
	public void uploadServiceCallCalls(JoinPoint joinPoint, Object rtv)
			throws Throwable {
		if (joinPoint.getArgs() == null) {// 没有参数
			return;
		}
		BLog bLog = new BLog();
		Object[] canshu = joinPoint.getArgs();
		MultipartFile file =(MultipartFile) canshu[0];
		HttpServletRequest request = (HttpServletRequest) canshu[1];
		BEmployee user =(BEmployee) request.getAttribute("user");
		String projId = request.getParameter("projId");
		String content = null;
		content = "上传了文档"+file.getOriginalFilename();
		bLog.setId(Common.generateUUID());
		bLog.setEmpId(user.getId());
		bLog.setEmpName(user.getName());
		bLog.setProjId(projId);
		bLog.setDeleteState("0");
		bLog.setContent(content);
		bLog.setProjId(projId);
		bLog.setCreateTime(new Date());
		bLog.setType("OPERATE");
		bLogService.insert(bLog);	
	}   
    /**
	 * 使用Java反射来获取被拦截方法(insert、update)的参数值,将参数值拼接为Map
	 */
	public Map<String,Object> adminOptionInfo(Object[] args,String mName)throws Exception{
		if (args == null) {
			return null;
		}
		String className = null;
		int index = 1;
		Map<String, Object> map = new HashMap<String,Object>();
		for (Object info : args) {
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			// 获取对象的所有方法
			Method[] methods = info.getClass().getDeclaredMethods();
			// 遍历方法，判断get方法
			for (Method method : methods) {
				String methodName = method.getName();
				// 判断是不是get方法
				if (methodName.indexOf("get") == -1) {// 不是get方法
					continue;// 不处理
				}
				Object rsValue = null;
				try {
					// 调用get方法，获取返回值
					rsValue = method.invoke(info);
					if (rsValue == null) {// 没有返回值
						continue;
					}
				} catch (Exception e) {
					continue;
				}
				// 将值加入内容中
				map.put(methodName , rsValue);
			}
			index++;
		}
		return map;
	}
	
	/**
	 * 使用Java反射来获取被拦截方法(insert、update)的参数值， 将参数值拼接为操作内容
	 */
	public String adminOptionContent(Object[] args, String mName)
			throws Exception {
		if (args == null) {
			return null;
		}
		StringBuffer rs = new StringBuffer();
		rs.append(mName);
		String className = null;
		int index = 1;
		// 遍历参数对象
		for (Object info : args) {
			// 获取对象类型
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			rs.append("[参数" + index + "，类型：" + className + "，值：");
			// 获取对象的所有方法
			Method[] methods = info.getClass().getDeclaredMethods();
			// 遍历方法，判断get方法
			for (Method method : methods) {
				String methodName = method.getName();
				// 判断是不是get方法
				if (methodName.indexOf("get") == -1) {// 不是get方法
					continue;// 不处理
				}
				Object rsValue = null;
				try {
					// 调用get方法，获取返回值
					rsValue = method.invoke(info);
					if (rsValue == null) {// 没有返回值
						continue;
					}
				} catch (Exception e) {
					continue;
				}
				// 将值加入内容中
				rs.append("(" + methodName + " : " + rsValue + ")");
			}
			rs.append("]");
			index++;
		}
		return rs.toString();
	}
    
    
    
    

}
